#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>
#include <errno.h>
#include <assert.h>

#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <functional>

using namespace std;


#include "cJSON.h"

int main(void)
{
    printf("==================== json Test =================\n");


    // 创建 JSON 对象
    cJSON* root = cJSON_CreateObject();


    // 添加键值对
    cJSON_AddStringToObject(root, "name", "AD");
    cJSON_AddNumberToObject(root, "age", 30);


    printf("-------------------------------------------------\n");

    // 添加嵌套json
    cJSON *pSon = cJSON_CreateObject();
    cJSON_AddBoolToObject(pSon, "flag", true);
    cJSON_AddStringToObject(pSon, "city", "北京");
    cJSON_AddStringToObject(pSon, "street", "工业大道");

    cJSON_AddItemToObject(root, "son", pSon);

    // 添加数组
    cJSON *array = cJSON_CreateArray();
    cJSON_AddItemToArray(array, cJSON_CreateString("读书"));
    cJSON_AddItemToArray(array, cJSON_CreateString("扫地"));
    cJSON_AddItemToArray(array, cJSON_CreateString("煮饭"));

    cJSON_AddItemToObject(root, "array", array);


    // 数组内添加完整jsonobj
    cJSON *arrayObject = cJSON_CreateArray();

    cJSON *pArraySon = cJSON_CreateObject();
    cJSON_AddBoolToObject(pArraySon, "aa", true);
    cJSON_AddStringToObject(pArraySon, "bb", "北京");
    cJSON_AddStringToObject(pArraySon, "cc", "工业大道");

    cJSON *pArraySon2 = cJSON_CreateObject();
    cJSON_AddBoolToObject(pArraySon2, "aa", false);
    cJSON_AddStringToObject(pArraySon2, "bb", "深圳");
    cJSON_AddStringToObject(pArraySon2, "cc", "海联路");

    cJSON_AddItemToArray(arrayObject, pArraySon);
    cJSON_AddItemToArray(arrayObject, pArraySon2);

    cJSON_AddItemToObject(root, "arrayObject", arrayObject);


    // 打印json
    char *pJsonStr = cJSON_Print(root);

    printf("json object : \n %s\n", pJsonStr);

    printf("\n>>>>>>>>>>>>>>>>>>> 解析json >>>>>>>>>>>>>>>>>>>>>\n");


    cJSON *pParseJson = cJSON_Parse(pJsonStr);
    if ( pParseJson == nullptr )
    {
        printf("error: %s\n", strerror(errno));
        return -1;
    }

    printf("=======>json object:\n%s\n", cJSON_Print(pParseJson));


    cJSON *pName = cJSON_GetObjectItem(pParseJson, "name");


    cJSON *pSonP = cJSON_GetObjectItem(pParseJson, "son");
    cJSON *pSonP_flag = cJSON_GetObjectItem(pSonP, "flag");
    cJSON *pSonP_city = cJSON_GetObjectItem(pSonP, "city");
    cJSON *pSonP_street = cJSON_GetObjectItem(pSonP, "street");

    printf(">>>>>>>>>>>>>>>>>>>>>>>>>打印>>>>>>>>>>>>>>>>>>>>>>\n");

    printf("name: %s\n", pName->valuestring);
    printf("son -- flag: %d, city: %s, street: %s\n", pSonP_flag->valueint, pSonP_city->valuestring, pSonP_street->valuestring);


    printf("\n\n");

    // 读取array里面的元素
    cJSON *pArray = cJSON_GetObjectItem(pParseJson, "array");
    
    int arraySize = cJSON_GetArraySize(pArray);
    printf("array:\b[ ");

    for(auto i=0; i<arraySize; i++)
    {
        cJSON *pItem = cJSON_GetArrayItem(pArray, i);
        printf("%s ", pItem->valuestring);        
    }

    printf(" \b]\n\n\n");


    // 读取arrayobject里面元素
    cJSON *pArrayObj = cJSON_GetObjectItem(pParseJson, "arrayObject");

    arraySize = cJSON_GetArraySize(pArrayObj);

    printf("arrayObj: \n");

    // 接收数据
    typedef struct Data
    {
        int flag;
        string addr;
        string loadName;

    } _Data;


    for(auto i=0; i<arraySize; i++)
    {
        cJSON *pItemObj = cJSON_GetArrayItem(pArrayObj, i);
        
        cJSON *paa = cJSON_GetObjectItem(pItemObj, "aa");
        cJSON *pbb = cJSON_GetObjectItem(pItemObj, "bb");
        cJSON *pcc = cJSON_GetObjectItem(pItemObj, "cc");

        Data data;
        data.addr = pbb->valuestring;
        data.loadName = pcc->valuestring;
        data.flag = paa->valueint;

        printf("aa: %d, bb: %s, dd: %s\n", data.flag, data.addr.c_str(), data.loadName.c_str());

    }

    // 释放内存
    cJSON_Delete(root);

    free(pJsonStr);
    pJsonStr = nullptr;


    return 0;

}

